package hu.diploma.core.util.transform;

import hu.diploma.common.vos.AddressVo;
import hu.diploma.common.vos.BaseVo;
import hu.diploma.common.vos.CallVo;
import hu.diploma.common.vos.DeviceVo;
import hu.diploma.common.vos.EmailVo;
import hu.diploma.common.vos.GroupVo;
import hu.diploma.common.vos.PersonVo;
import hu.diploma.common.vos.PersonalDataVo;
import hu.diploma.common.vos.SmsMmsVo;
import hu.diploma.common.vos.StructuredNameVo;
import hu.diploma.common.vos.UserVo;
import hu.diploma.core.entity.Address;
import hu.diploma.core.entity.BaseEntity;
import hu.diploma.core.entity.Call;
import hu.diploma.core.entity.Device;
import hu.diploma.core.entity.Email;
import hu.diploma.core.entity.Group;
import hu.diploma.core.entity.Person;
import hu.diploma.core.entity.PersonalData;
import hu.diploma.core.entity.SmsMms;
import hu.diploma.core.entity.StructuredName;
import hu.diploma.core.entity.User;

import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.dozer.DozerBeanMapper;

public class TransformUtil {
	public static DozerBeanMapper beanMapper = new DozerBeanMapper();
	private static Logger logger = Logger.getLogger(TransformUtil.class);

	public static BaseVo entityToVo(BaseEntity entity) throws Exception {
		TransformUtil.logger.info("entityToVo in " + entity);
		if (entity == null) {
			return null;
		}

		if (entity instanceof PersonalData) {
			PersonalDataVo map = TransformUtil.beanMapper.map(entity, PersonalDataVo.class);
			TransformUtil.logger.info("entityToVo out " + map);
			return map;
		} else if (entity instanceof User) {
			UserVo map = TransformUtil.beanMapper.map(entity, UserVo.class);
			TransformUtil.logger.info("entityToVo out " + map);
			return map;
		} else if (entity instanceof Device) {
			DeviceVo map = TransformUtil.beanMapper.map(entity, DeviceVo.class);
			TransformUtil.logger.info("entityToVo out " + map);
			return map;

		} else if (entity instanceof Person) {
			PersonVo personVo = TransformUtil.beanMapper.map(entity, PersonVo.class);

			if (((Person) entity).getPersonalDatas() != null) {
				int index = 0;
				for (PersonalData dataVo : ((Person) entity).getPersonalDatas()) {
					personVo.getPersonalDatas().get(index).setPerson(personVo);
				}
			}

			if (((Person) entity).getAddresses() != null) {
				int index = 0;
				for (Address address : ((Person) entity).getAddresses()) {
					personVo.getAddresses().get(index).setPerson(personVo);
				}
			}

			if (((Person) entity).getStructuredName() != null) {
				personVo.getStructuredName().setPerson(personVo);
			}

			TransformUtil.logger.info("entityToVo out " + personVo);
			return personVo;
		} else if (entity instanceof Group) {
			GroupVo map = TransformUtil.beanMapper.map(entity, GroupVo.class);
			TransformUtil.logger.info("entityToVo out " + map);
			return map;
		} else if (entity instanceof Address) {
			AddressVo map = TransformUtil.beanMapper.map(entity, AddressVo.class);
			TransformUtil.logger.info("entityToVo out " + map);
			return map;
		} else if (entity instanceof StructuredName) {
			StructuredNameVo map = TransformUtil.beanMapper.map(entity, StructuredNameVo.class);
			TransformUtil.logger.info("entityToVo out " + map);
			return map;
		} else if (entity instanceof Email) {
			EmailVo map = TransformUtil.beanMapper.map(entity, EmailVo.class);
			TransformUtil.logger.info("entityToVo out " + map);
			return map;
		} else if (entity instanceof SmsMms) {
			SmsMmsVo map = TransformUtil.beanMapper.map(entity, SmsMmsVo.class);
			TransformUtil.logger.info("entityToVo out " + map);
			return map;
		} else if (entity instanceof Call) {
			CallVo map = TransformUtil.beanMapper.map(entity, CallVo.class);
			TransformUtil.logger.info("entityToVo out " + map);
			return map;
		}

		throw new Exception("Entity was not mapped" + entity.getClass().getName());

	}

	public static BaseEntity VoToEntity(BaseVo baseVo) throws Exception {
		TransformUtil.logger.info("VoToEntity in " + baseVo);
		if (baseVo == null) {
			return null;
		}

		if (baseVo instanceof PersonalDataVo) {
			PersonalData map = TransformUtil.beanMapper.map(baseVo, PersonalData.class);
			TransformUtil.logger.info("VoToEntity out " + map);
			return map;
		} else if (baseVo instanceof UserVo) {
			User map = TransformUtil.beanMapper.map(baseVo, User.class);
			TransformUtil.logger.info("VoToEntity out " + map);
			return map;
		} else if (baseVo instanceof DeviceVo) {
			Device map = TransformUtil.beanMapper.map(baseVo, Device.class);
			TransformUtil.logger.info("VoToEntity out " + map);
			return map;

		} else if (baseVo instanceof PersonVo) {

			Person person = TransformUtil.beanMapper.map(baseVo, Person.class);

			if (((PersonVo) baseVo).getPersonalDatas() != null) {
				int index = 0;
				for (PersonalDataVo dataVo : ((PersonVo) baseVo).getPersonalDatas()) {
					person.getPersonalDatas().get(index).setPerson(person);
					index++;
				}
			}

			if (((PersonVo) baseVo).getAddresses() != null) {
				int index = 0;
				for (AddressVo address : ((PersonVo) baseVo).getAddresses()) {
					person.getAddresses().get(index).setPerson(person);
					index++;
				}
			}

			if (((PersonVo) baseVo).getStructuredName() != null) {
				person.getStructuredName().setPerson(person);
			}
			TransformUtil.logger.info("VoToEntity out " + person);
			return person;

		} else if (baseVo instanceof GroupVo) {
			Group map = TransformUtil.beanMapper.map(baseVo, Group.class);
			TransformUtil.logger.info("VoToEntity out " + map);
			return map;
		} else if (baseVo instanceof AddressVo) {
			Address map = TransformUtil.beanMapper.map(baseVo, Address.class);
			TransformUtil.logger.info("VoToEntity out " + map);
			return map;
		} else if (baseVo instanceof StructuredNameVo) {
			StructuredName map = TransformUtil.beanMapper.map(baseVo, StructuredName.class);
			TransformUtil.logger.info("VoToEntity out " + map);
			return map;
		} else if (baseVo instanceof EmailVo) {
			Email map = TransformUtil.beanMapper.map(baseVo, Email.class);
			TransformUtil.logger.info("VoToEntity out " + map);
			return map;
		} else if (baseVo instanceof SmsMmsVo) {
			SmsMms map = TransformUtil.beanMapper.map(baseVo, SmsMms.class);
			TransformUtil.logger.info("VoToEntity out " + map);
			return map;
		} else if (baseVo instanceof CallVo) {
			Call map = TransformUtil.beanMapper.map(baseVo, Call.class);
			TransformUtil.logger.info("VoToEntity out " + map);
			return map;
		}

		throw new Exception("Vo was not mapped :" + baseVo.getClass().getName());

	}

	public static List<BaseVo> entityToVo(List<BaseEntity> entity) throws Exception {
		List<BaseVo> rv = new LinkedList<BaseVo>();
		for (BaseEntity baseEntity : entity) {
			rv.add(TransformUtil.entityToVo(baseEntity));
		}
		return rv;

	}

	public static List<BaseEntity> VoToEntity(List<BaseVo> baseVos) throws Exception {
		List<BaseEntity> rv = new LinkedList<BaseEntity>();
		for (BaseVo baseVo : baseVos) {
			rv.add(TransformUtil.VoToEntity(baseVo));
		}
		return rv;

	}
}
